/*
 * ConversionDiscountDAO.java
 *
 * Created on April 10, 2007, 12:00 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package edu.byu.isys413.jjenkins.data;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
 * This class contains the CRUD standard methods, which will be used to access business objecst and database
 * @author Intex2Week
 */
public class ConversionDiscountDAO
{
    
    private static ConversionDiscountDAO instance = null;
    private PreparedStatement readUnitPrice = null;
    private PreparedStatement insertConvDiscount = null;
    private PreparedStatement readConvDiscount = null;
    private PreparedStatement updateConvDiscount = null;
    /**
     * This method read the transaction line
     */
    public PreparedStatement readByTS;
    
    
    /** Creates a new instance of ConversionDiscountDAO */
    private ConversionDiscountDAO() {
    }
    
   /**
     * This method implements the singleton pattern. It insures that only
     * on instance of ConversionDiscountDAO exists
     * @return BackupDAO
     */
    public static synchronized ConversionDiscountDAO getInstance() {
        if (instance == null) {
            instance = new ConversionDiscountDAO();
        }
        return instance;
    }//end method
    
    /** This method creates a new RevenueSourceBO with a unique QUID, puts the COnversion
     * in cache, and then returns it to the calling method.
     * @throws edu.byu.isys413.jjenkins.data.DataException 
     * @return BAckup BO
     */
    public ConversionDiscount createDiscount(double percent, int quantity)throws Exception{
        ConversionDiscount p = createDiscount(GUID.generate(),percent,quantity);
        Cache.getInstance().put(p.getId (),p);
        return p;
    }
    
    /**
     * create print format
     */
    public ConversionDiscount createDiscount(String guid, double percent, int quantity) throws Exception{
        ConversionDiscount p = new ConversionDiscount(guid);
        p.setPercent (percent);
        p.setQuantity (quantity);
        Cache.getInstance().put(p.getId (),p);
        return p;
    }
    
    /**
     * insert print format
     */
    public void insertConvDiscount(ConversionDiscount p)throws Exception{
        Connection conn = ConnectionPool.getInstance().get();
        this.insertConvDiscount(p,conn);
    }
    /**
     * insert print format
     */
    public void insertConvDiscount(ConversionDiscount p , Connection conn)throws Exception{
        try {
            this.insertConvDiscount = conn.prepareStatement("insert into conversion_discount values" +
                    "(?,?,?)");
            insertConvDiscount.setString(1,p.getId ());
            insertConvDiscount.setDouble (2,p.getPercent ());
            insertConvDiscount.setDouble (3,p.getQuantity ());
            insertConvDiscount.execute();
            ConnectionPool.getInstance().release(conn);
        } catch (Exception ex) {
            ex.printStackTrace();
            conn.rollback();
            ConnectionPool.getInstance().release(conn);
            throw ex;
        }
    }
    
    /**
     * update print format
     */
    public void updateConvDiscount(ConversionDiscount f)throws Exception{
        Connection conn = ConnectionPool.getInstance().get();
        updateConvDiscount(f,conn);
     }
    /**
     * update print format
     */
    public void updateConvDiscount(ConversionDiscount f, Connection conn)throws Exception{
        try {
            this.updateConvDiscount = conn.prepareStatement("update conversion_discount SET percent=?, quantity=? WHERE guid=?");
            updateConvDiscount.setDouble (1,f.getPercent ());
            updateConvDiscount.setDouble(2,f.getQuantity ());
             updateConvDiscount.setString(3,f.getId ());
            updateConvDiscount.executeUpdate();
            ConnectionPool.getInstance().release(conn);
        } catch (Exception ex) {
            ex.printStackTrace();
            conn.rollback();
            ConnectionPool.getInstance().release(conn);
            throw ex;
        }         
    }
    
    /**
     * This is the public read statement.  It loads an existing record
     * from the database.
     * @param id id of ConversionDiscount
     * @throws edu.byu.isys413.jjenkins.data.DataException 
     * @return BackupBO
     */
    public ConversionDiscount readConvDiscount(String guid)throws Exception{
        ConversionDiscount p = null;
        Connection conn = ConnectionPool.getInstance().get();
        p = readConvDiscount(guid,conn);
        return p;
    }
    
     /**
     *  This is a package method that is called by the public read (above) or
     *  by another DAO.  Either way we already have a connection to the database
     *  to use.  The user (controller) code never calls this one directly, since
     *  it can't know about Connection objects or SQLExceptions.
     * @param id id of ConversionDiscount
     * @param conn connection
     * @throws java.sql.SQLException 
     * @throws edu.byu.isys413.jjenkins.data.DataException 
     * @return BackupBO
     */
    public ConversionDiscount readConvDiscount(String guid, Connection conn)throws Exception{
        ConversionDiscount p = null;
        if(Cache.getInstance().containsKey(guid)){
            p = (ConversionDiscount)Cache.getInstance().get(guid);
            Cache.getInstance().touch(guid);
            
        }else{
            try {
                
                this.readConvDiscount = conn.prepareStatement("select * from conversion_discount where guid = ?");
                this.readConvDiscount.setString(1,guid);
                ResultSet rs = this.readConvDiscount.executeQuery();
                while(rs.next()){
                    p = this.createDiscount(rs.getString("guid"),
                            rs.getDouble ("percent"),
                            rs.getInt ("quantity"));
                    
                }
                ConnectionPool.getInstance().release(conn);
            } catch (Exception ex) {
                ex.printStackTrace();
                conn.rollback();
                ConnectionPool.getInstance().release(conn);
                throw ex;
            }
            
        }
        return p;
    }

      /**
     * read discount for tx
     */
    public ConversionDiscount readDicountForTx(int quantity)throws Exception{
        Connection conn = ConnectionPool.getInstance().get();
        return readDiscountForTx(quantity,conn);
    }
    
    /**
     * read discount for tx
     */
    public ConversionDiscount readDiscountForTx(int quantity, Connection conn)throws Exception {
        ConversionDiscount greatest = null;
        List <ConversionDiscount> temp = new LinkedList();
        try {
            this.readConvDiscount = conn.prepareStatement("select * from conversion_discount where quantity < ?");
            readConvDiscount.setString (1,String.valueOf(quantity));
            ResultSet rs = readConvDiscount.executeQuery();
            ConnectionPool.getInstance().release(conn);
            while(rs.next()){
                ConversionDiscount cd = this.createDiscount (Double.parseDouble(rs.getString("percent")),
                        Integer.parseInt(rs.getString("quantity")));
                temp.add(cd);
            }
            greatest = temp.get(0);
            for(int i = 0; i < temp.size(); i++){
                ConversionDiscount tester = temp.get(i);
                if(greatest.getPercent() < tester.getPercent()){
                    greatest = tester;
                }
            }            
        } catch (Exception ex) {
            ex.printStackTrace();
            conn.rollback();
            ConnectionPool.getInstance().release(conn);
            throw ex;
        }
        return greatest;
    }
    
   
    
     
   
    
    

    
}
